{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import logging\n",
    "\n",
    "logging.basicConfig(\n",
    "    filename='log.log',          # 日志文件名\n",
    "    filemode='w',               # 写入模式：'a'追加，'w'覆盖\n",
    "    level=logging.INFO,         # 记录级别\n",
    "    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',\n",
    "    datefmt='%Y-%m-%d %H:%M:%S'\n",
    ")\n",
    "\n",
    "logging.info('这是一条信息日志')\n",
    "logging.warning('这是一条信息日志Warn')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import logging\n",
    "ch=logging.StreamHandler()  # 创建一个输出到控制台的处理器\n",
    "ch.setLevel(logging.DEBUG)  # 设置处理器的日志级别\n",
    "formatter=logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(funcName)s - %(message)s')  # 设置日志格式\n",
    "ch.setFormatter(formatter)  # 将格式应用到处理器\n",
    "logger=logging.getLogger('__main__')  # 创建一个日志记录器\n",
    "logger.addHandler(ch)  # 将处理器添加到日志记录器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2025-06-02 21:55:59,158 - myapp - <module> - INFO - This is an info message!\n",
      "2025-06-02 21:55:59,160 - myapp - <module> - INFO - (1) Running Module core\n",
      "2025-06-02 21:55:59,160 - ERROR - [core fmt:myliblog.core -do_core - 27] - An error demo in core module\n",
      "2025-06-02 21:55:59,161 - myapp - <module> - INFO - (2) Running Module utils\n",
      "2025-06-02 21:55:59,162 - INFO - [utils fmt:myliblog.utils -helper - 16] - Some useful info from utils\n",
      "2025-06-02 21:55:59,163 - WARNING - [utils fmt:myliblog.utils -helper - 17] - This is a warning from utils\n",
      "2025-06-02 21:55:59,164 - ERROR - [utils fmt:myliblog.utils -helper - 18] - An error demo occurred in utils\n",
      "2025-06-02 21:55:59,164 - myapp - <module> - INFO - (3) Running Module auxiliary\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "myliblog package initialized\n"
     ]
    }
   ],
   "source": [
    "import logging\n",
    "from myliblog import core\n",
    "from myliblog import utils\n",
    "from myliblog import auxiliary\n",
    "\n",
    "\n",
    "def setup_logging():\n",
    "    # 创建一个顶级 logger\n",
    "    logger = logging.getLogger(\"myapp\")\n",
    "    logger.setLevel(logging.DEBUG)  # 根 logger 级别为 DEBUG\n",
    "\n",
    "    # 创建两个 handler：控制台 + 文件\n",
    "    # 控制台的日志级别为 INFO\n",
    "    console_handler = logging.StreamHandler()\n",
    "    console_handler.setLevel(logging.INFO)\n",
    "\n",
    "    # 文件的日志级别为 DEBUG\n",
    "    file_handler = logging.FileHandler(\"app.log\", mode=\"w\", encoding=\"utf-8\")\n",
    "    file_handler.setLevel(logging.DEBUG)\n",
    "\n",
    "    # 定义格式器\n",
    "    formatter = logging.Formatter(\n",
    "        fmt=\"%(asctime)s - %(name)s - %(funcName)s - %(levelname)s - %(message)s\"\n",
    "    )\n",
    "    console_handler.setFormatter(formatter)\n",
    "    file_handler.setFormatter(formatter)\n",
    "\n",
    "    # 添加 handler 到根 logger\n",
    "    logger.addHandler(console_handler)\n",
    "    logger.addHandler(file_handler)\n",
    "\n",
    "    # 可选：关闭 propagate，防止重复输出\n",
    "    logger.propagate = False\n",
    "    return logger\n",
    "\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    logger = setup_logging()\n",
    "\n",
    "    # 获取子模块的 logger\n",
    "    logger_core = logging.getLogger(\"myliblog.core\")\n",
    "    logger_utils = logging.getLogger(\"myliblog.utils\")\n",
    "    # logger_auxiliary = logging.getLogger(\"myliblog.auxiliary\")\n",
    "\n",
    "    # 获取被调用模块的logger对象后,可以通过该对象设置模块代码中的日志行为,比如级别\n",
    "    logger_core.setLevel(logging.ERROR)  # 设置 core 模块的日志级别为 ERROR\n",
    "    logger_utils.setLevel(logging.INFO)\n",
    "    # logger_auxiliary.setLevel(logging.INFO)\n",
    "\n",
    "    logger.debug(\"This is a debug message!\")\n",
    "    logger.info(\"This is an info message!\")\n",
    "    \n",
    "    logger.info(\"(1) Running Module core\")\n",
    "    core.do_core()  # 输出 ERROR 日志\n",
    "    logger.info(\"(2) Running Module utils\")\n",
    "    utils.helper()  # 输出 Info 日志\n",
    "    logger.info(\"(3) Running Module auxiliary\")\n",
    "    auxiliary.some_function()  # 输出 Info 日志\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import myliblog.core\n",
    "\n",
    "myliblog.core.do_core()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
